/**
 * <pre>
 * Title: 		AppUserServiceImpl.java
 * Project: 	MSOOS
 * Author:		pengfangliang
 * Create:	 	2012-5-29 上午11:28:00
 * Copyright: 	Copyright (c) 2012
 * Company:		Shenzhen Helper
 * <pre>
 */
package com.hengpeng.itfinoss.service.impl;

import java.util.ArrayList;
import java.util.Date;
import java.util.LinkedHashMap;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map.Entry;
import java.util.Set;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.hengpeng.common.acl.vo.Passport.Token;
import com.hengpeng.common.exception.ResourceNotFoundException;
import com.hengpeng.common.persist.entity.AbstractEntity.BoolValue;
import com.hengpeng.common.persist.query.DynamicQuery;
import com.hengpeng.common.persist.query.Restrictions;
import com.hengpeng.common.persist.query.model.Order;
import com.hengpeng.common.persist.query.model.Order.OrderType;
import com.hengpeng.common.util.StringHelper;
import com.hengpeng.itfinbase.persist.AppGroup;
import com.hengpeng.itfinbase.persist.AppRole;
import com.hengpeng.itfinbase.persist.AppUser;
import com.hengpeng.itfinbase.persist.AppUser.UserStatus;
import com.hengpeng.itfinbase.persist.PermissionPo;
import com.hengpeng.itfinbase.persist.ShortcutMenu;
import com.hengpeng.itfinoss.service.AppUserService;
import com.hengpeng.itfinoss.service.ServiceFactory;

/**
 * <pre>
 * TODO 输入类型说明
 * </pre>
 * @author pengfangliang
 * @version 1.0, 2012-5-29
 */
@Service
public class AppUserServiceImpl implements AppUserService
{
	@Autowired
	private ServiceFactory serviceFactory;

	@Override
	public AppUser modify(Long id, String userNo, String loginName, String nickName, String newPwd, String realName,
			String phone, String email, UserStatus state, Token token, Date lastLogin, Set<AppGroup> groups,
			Set<AppRole> roles)
	{
		AppUser user = serviceFactory.getPersistService().get(AppUser.class, id);
		if (user == null)
		{
			throw new ResourceNotFoundException(id);
		}
		if (userNo != null)
		{
			user.setUserNo(userNo);
		}
		if (loginName != null)
		{
			user.setLoginName(loginName);
		}
		if (nickName != null)
		{
			user.setNickName(nickName);
		}
		if (newPwd != null)
		{
			user.setPassword(newPwd);
		}
		if (realName != null)
		{
			user.setRealName(realName);
		}
		if (phone != null)
		{
			user.setPhone(phone);
		}
		if (email != null)
		{
			user.setEmail(email);
		}
		if (state != null)
		{
			user.setState(state);
		}
		if (token != null)
		{
			user.setToken(token);
		}
		if (groups != null)
		{
			user.setGroups(groups);
		}
		if (roles != null)
		{
			user.setRoles(roles);
		}
		if (lastLogin != null)
		{
			user.setLastLogin(lastLogin);
		}

		Date date = new Date();
		user.setLastUpdate(date);

		return serviceFactory.getPersistService().update(user);
	}

	public AppUser save(String userNo, String loginName, String nickName, String password, String realName,
			String phone, String email, UserStatus state, Token token, Set<AppGroup> groups, Set<AppRole> roles)
	{
		AppUser user = new AppUser();
		user.setUserNo(userNo);
		user.setLoginName(loginName);
		user.setNickName(nickName);
		user.setPassword(password);
		user.setRealName(realName);
		user.setPhone(phone);
		user.setEmail(email);
		user.setState(state);
		user.setToken(token);
		if (groups != null && groups.size() > 0)
		{
			user.setGroups(groups);
		}
		if (roles != null && roles.size() > 0)
		{
			user.setRoles(roles);
		}
		Date date = new Date();
		user.setCreateTime(date);
		user.setLastUpdate(date);
		return serviceFactory.getPersistService().save(user);
	}

	public List<AppUser> findUsers(String loginName, String userNo, String realName, String email, int currentPage,
			int pageSize, LinkedHashMap<String, OrderType> sort, String counterId)
	{
		DynamicQuery pagination = new DynamicQuery(AppUser.class);
		pagination.add(Restrictions.eq("loginName", loginName));
		pagination.add(Restrictions.eq("userNo", userNo));
		pagination.add(Restrictions.eq("realName", realName));
		pagination.add(Restrictions.eq("email", email));
		pagination.add(Restrictions.eq("counterId", counterId));
		pagination.setPageIndex(currentPage);
		pagination.setPageSize(pageSize);
		if (sort != null)
		{
			for (Entry<String, OrderType> iterable_element : sort.entrySet())
			{
				if (iterable_element.getValue() == Order.OrderType.ASC)
				{
					pagination.asc(iterable_element.getKey());
				}
				else
				{
					pagination.desc(iterable_element.getKey());
				}
			}
		}
		return serviceFactory.getPersistService().find(AppUser.class, pagination);
	}

	public List<AppRole> findUserRoleByIds(Long[] ids)
	{
		DynamicQuery query = new DynamicQuery(AppRole.class);
		query.add(Restrictions.inArray("id", ids));
		return serviceFactory.getPersistService().find(AppRole.class, query);
	}

	public List<AppGroup> findGroupByIds(Long[] ids)
	{
		DynamicQuery query = new DynamicQuery(AppGroup.class);
		query.add(Restrictions.inArray("id", ids));
		return serviceFactory.getPersistService().find(AppGroup.class, query);
	}

	public List<AppUser> findUserByIds(Long[] ids)
	{
		DynamicQuery pagination = new DynamicQuery(AppUser.class);
		pagination.add(Restrictions.inArray("id", ids));
		return serviceFactory.getPersistService().find(AppUser.class, pagination);
	}

	public void delete(String operateUser, Set<Object> userId)
	{
		List<AppUser> list = findUserByIds(userId.toArray(new Long[userId.size()]));
		for (AppUser appUser : list)
		{
			serviceFactory.getPersistService().delete(AppUser.class, appUser.getId());
		}
	}

	public List<AppRole> findRoleWithPage(String name, int currentPage, int pageSize,
			LinkedHashMap<String, OrderType> sort)
	{
		DynamicQuery query = new DynamicQuery(AppRole.class);
		if (!StringHelper.isEmpty(name))
		{
			query.add(Restrictions.like("name", "%" + name + "%"));
		}
		query.setPageIndex(currentPage);
		query.setPageSize(pageSize);
		if (sort != null)
		{
			for (Entry<String, OrderType> iterable_element : sort.entrySet())
			{
				if (iterable_element.getValue() == Order.OrderType.ASC)
				{
					query.asc(iterable_element.getKey());
				}
				else
				{
					query.desc(iterable_element.getKey());
				}
			}
		}
		return serviceFactory.getPersistService().find(AppRole.class, query);
	}

	public Long findRoleCount(String name)
	{
		DynamicQuery query = new DynamicQuery(AppRole.class);
		if (!StringHelper.isEmpty(name))
		{
			query.add(Restrictions.like("name", "%" + name + "%"));
		}
		return serviceFactory.getPersistService().findPageCount(query, null);
	}

	public List<AppRole> findUserRoles(Long[] ids, String name)
	{
		DynamicQuery pagination = new DynamicQuery(AppRole.class);
		pagination.add(Restrictions.inArray("id", ids));
		pagination.add(Restrictions.eq("name", name));
		return serviceFactory.getPersistService().find(AppRole.class, pagination);
	}

	public AppRole saveRole(String name, String description, Set<PermissionPo> permissions)
	{
		AppRole role = new AppRole();
		role.setName(name);
		role.setDescription(description);
		if (permissions != null && permissions.size() > 0)
		{
			role.setPermission(permissions);
		}
		return serviceFactory.getPersistService().update(role);
	}

	public void deleteRole(Set<Object> roleId)
	{
		List<AppRole> list = findUserRoleByIds(roleId.toArray(new Long[roleId.size()]));
		for (AppRole appRole : list)
		{
			serviceFactory.getPersistService().delete(AppRole.class, appRole.getId());
		}
	}

	public AppRole modifyRole(Long id, String name, String description, Set<PermissionPo> permissions)
	{
		AppRole role = serviceFactory.getPersistService().get(AppRole.class, id);
		if (role == null)
		{
			throw new ResourceNotFoundException(id);
		}
		if (name != null)
		{
			role.setName(name);
		}
		if (description != null)
		{
			role.setDescription(description);
		}
		if (permissions != null)
		{
			role.setPermission(permissions);
		}
		return serviceFactory.getPersistService().update(role);
	}

	public Set<AppGroup> findAllGroupSort(Long groupId)
	{
		/* 顶级分组 */
		List<AppGroup> list = findLevelGroup(null);
		Set<AppGroup> set = new LinkedHashSet<AppGroup>();
		iterator(list, set, groupId);
		return set;
	}

	private List<AppGroup> findLevelGroup(Long level)
	{
		DynamicQuery pagination = new DynamicQuery(AppGroup.class);
		if (level == null)
		{
			pagination.add(Restrictions.isNull("parent_id"));
		}
		else
		{
			pagination.add(Restrictions.eq("parent_id", level));
		}
		return serviceFactory.getPersistService().find(AppGroup.class, pagination);
	}

	private void iterator(List<AppGroup> list, Set<AppGroup> group, Long groupId)
	{
		if (list != null && list.size() > 0)
		{
			for (AppGroup groups : list)
			{
				if (groupId != null && groups.getId().equals(groupId))
				{
					continue;
				}
				group.add(groups);
				List<AppGroup> subList = findLevelGroup(groups.getId());
				iterator(subList, group, groupId);
			}
		}
	}

	public List<AppGroup> findChildByIds(Long[] ids)
	{
		DynamicQuery pagination = new DynamicQuery(AppGroup.class);
		pagination.add(Restrictions.inArray("parent_id", ids));
		return serviceFactory.getPersistService().find(AppGroup.class, pagination);
	}

	public AppGroup saveGroup(String name, String description, AppGroup parent, String extValue)
	{
		AppGroup group = new AppGroup();
		group.setName(name);
		group.setDescription(description);
		group.setExtValue(extValue);

		group.setParent(parent);
		return serviceFactory.getPersistService().save(group);
	}

	public void deleteGroup(Set<Object> ids)
	{
		List<AppGroup> list = findGroupByIds(ids.toArray(new Long[ids.size()]));
		for (AppGroup appGroup : list)
		{
			serviceFactory.getPersistService().delete(AppGroup.class, appGroup.getId());
		}
	}

	public AppGroup modifyGroup(Long id, String name, String description, AppGroup parent, String extValue)
	{
		AppGroup group = serviceFactory.getPersistService().get(AppGroup.class, id);
		if (group == null)
		{
			throw new ResourceNotFoundException(id);
		}
		if (name != null)
		{
			group.setName(name);
		}
		if (description != null)
		{
			group.setDescription(description);
		}
		if (extValue != null)
		{
			group.setExtValue(extValue);
		}
		group.setParent(parent);
		return serviceFactory.getPersistService().update(group);
	}

	public List<AppGroup> findGroupWithPage(String name, Long parentId, int currentPage, int pageSize,
			LinkedHashMap<String, OrderType> sort)
	{
		DynamicQuery query = new DynamicQuery(AppGroup.class);
		if (!StringHelper.isEmpty(name))
			query.add(Restrictions.like("name", "%" + name + "%"));
		query.add(Restrictions.eq("parent_id", parentId));
		query.setPageIndex(currentPage);
		query.setPageSize(pageSize);

		if (sort != null)
		{
			for (Entry<String, OrderType> iterable_element : sort.entrySet())
			{
				if (iterable_element.getValue() == Order.OrderType.ASC)
				{
					query.asc(iterable_element.getKey());
				}
				else
				{
					query.desc(iterable_element.getKey());
				}
			}
		}
		return serviceFactory.getPersistService().find(AppGroup.class, query);
	}

	public Long findGroupCount(String name, Long parentId)
	{
		DynamicQuery query = new DynamicQuery(AppGroup.class);
		if (!StringHelper.isEmpty(name))
			query.add(Restrictions.like("name", "%" + name + "%"));
		query.add(Restrictions.eq("parent_id", parentId));
		return serviceFactory.getPersistService().findPageCount(query, null);
	}

	public List<ShortcutMenu> findShortcutMenu(Long userId, BoolValue value, Integer pageIndex, Integer pageSize)
	{
		DynamicQuery query = new DynamicQuery(ShortcutMenu.class);
		query.add(Restrictions.eq("userId", userId));
		query.add(Restrictions.eq("isShare", value == null ? value : value.toString()));
		query.setPageIndex(pageIndex);
		query.setPageSize(pageSize);
		return serviceFactory.getPersistService().find(ShortcutMenu.class, query);
	}

	public Long findShortcutMenuCount(Long userId, BoolValue value)
	{
		DynamicQuery query = new DynamicQuery(ShortcutMenu.class);
		query.add(Restrictions.eq("userId", userId));
		query.add(Restrictions.eq("isShare", value == null ? value : value.toString()));
		return serviceFactory.getPersistService().findPageCount(query, null);
	}

	public List<ShortcutMenu> findShareShortcutMenu(Long excludeUserId, Integer pageIndex, Integer pageSize)
	{
		DynamicQuery query = new DynamicQuery(ShortcutMenu.class);
		query.add(Restrictions.eq("userId", excludeUserId));
		query.add(Restrictions.eq("isShare", BoolValue.YES));
		query.setPageIndex(pageIndex);
		query.setPageSize(pageSize);
		query.getSqlResult().getSql();
		return serviceFactory.getPersistService().find(ShortcutMenu.class, query);
	}

	public Long findShareShortcutMenuCount(Long excludeUserId)
	{
		DynamicQuery query = new DynamicQuery(ShortcutMenu.class);
		query.add(Restrictions.eq("userId", excludeUserId));
		query.add(Restrictions.eq("isShare", BoolValue.YES));
		return serviceFactory.getPersistService().findPageCount(query, null);
	}

	public void saveShortcutMenu(ShortcutMenu menu)
	{
		serviceFactory.getPersistService().save(menu);
	}

	public void modifyShortcutMenu(ShortcutMenu menu)
	{
		serviceFactory.getPersistService().update(menu);
	}

	public void removeShortcutMenu(Long[] id)
	{
		List<ShortcutMenu> list = new ArrayList<ShortcutMenu>();
		DynamicQuery query = new DynamicQuery(ShortcutMenu.class);
		query.add(Restrictions.inArray("id", id));
		list = serviceFactory.getPersistService().find(ShortcutMenu.class, query);
		for (ShortcutMenu shortcutMenu : list)
		{
			serviceFactory.getPersistService().delete(ShortcutMenu.class, shortcutMenu.getId());
		}

	}

}
